markdown-text-editor 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 nezanuha
3
+ Copyright (c) 2026 nezanuha
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # MarkdownEditor — Lightweight JavaScript Markdown Editor with WYSIWYG & Plain Mode
1
+ # Markdown Text Editor
2
2
 
3
- ### The Native-First JavaScript Markdown Editor
3
+ ### Toolbar, live preview and WYSIWYG on the textarea you already have
4
4
 
5
5
  [![npm installs][npm_installs]](https://www.npmjs.com/package/markdown-text-editor)
6
6
  [![Jsdelivr hits][jsdelivr]](https://cdn.jsdelivr.net/npm/markdown-text-editor)
@@ -13,27 +13,34 @@ A lightweight, embeddable JavaScript Markdown editor that transforms a standard
13
13
 
14
14
  A native-first Markdown editor built on a standard textarea. No data binding, no API — just drop it in and your forms keep working as-is.
15
15
 
16
+ **Works standalone.** No Frutjam, no Tailwind, no framework required, the styles are bundled.
17
+
18
+ ![Hybrid mode: headings, bold text and list markers styled live inside the textarea while the Markdown syntax stays visible](https://cdn.frutjam.com/media/plugins/hybrid-mode-markdown-editor.webp)
19
+
20
+ <sub>Hybrid mode. Text is styled as you type and the Markdown stays where it is, because this is your `<textarea>`, not a copy of it.</sub>
21
+
16
22
  > **No complex APIs. No data binding. No JSON schemas.** Just a `<textarea>` that types Markdown and submits like any normal form field — enhanced with a rich toolbar, live preview, and WYSIWYG hybrid mode.
17
23
 
18
24
  ## ⭐ Why developers choose this over EasyMDE / SimpleMDE
19
25
 
20
- Most JavaScript markdown editors (EasyMDE, SimpleMDE, CodeMirror-based editors) replace your `<textarea>` with a custom element — which means you have to write extra code to extract the value before form submission, sync state manually, and learn a new API just to read or set content.
26
+ Most JavaScript markdown editors (EasyMDE, SimpleMDE, CodeMirror-based editors) hide your `<textarea>` and edit a copy, writing the value back when the form is submitted. That holds up until something else needs the field: a `required` input the browser cannot focus blocks the submit entirely, and `.value` or `FormData` read before submit returns an empty string, which breaks htmx, Turbo, Livewire, autosave and unsaved-changes guards.
21
27
 
22
28
  **MarkdownEditor is different.** It sits transparently on top of your existing `<textarea>`:
23
29
 
24
30
  | Feature | MarkdownEditor | EasyMDE / SimpleMDE |
25
31
  |---|---|---|
26
- | Native `<textarea>` preserved | ✅ | ❌ Replaced |
27
- | Form submission works as-is | ✅ | ❌ Requires extra JS |
28
- | Get/set value via `.value` | ✅ | ❌ Custom API needed |
32
+ | Native `<textarea>` preserved | ✅ | ❌ Hidden, edited as a copy |
33
+ | Works with `required` fields | ✅ | ❌ Browser blocks the submit |
34
+ | `.value` correct before submit | ✅ | ❌ Empty until the form submits |
35
+ | Serialises with `FormData`, htmx, Turbo | ✅ | ❌ Needs the editor's own API |
29
36
  | WYSIWYG hybrid mode | ✅ | ❌ |
30
- | CSP-compatible (no inline JS) | ✅ | ❌ |
31
- | Zero CSS conflicts | ✅ | ❌ |
32
- | RTL support | ✅ | ❌ |
37
+ | Inline event handlers (CSP) | ✅ None | Some |
38
+ | RTL support | ✅ Built in | Via CodeMirror's `direction` option |
33
39
  | Built-in Find & Replace | ✅ | ❌ |
40
+ | Swap the markdown parser | ✅ | ❌ |
34
41
  | Keyboard shortcuts | ✅ | Partial |
35
42
  | Dark mode / theming | ✅ | Limited |
36
- | ~116KB bundle | ✅ | ~300KB+ |
43
+ | Bundle size, gzipped | 51 KB | 107 KB (JS + CSS) |
37
44
 
38
45
  ## 🚀 Quick Start
39
46
 
@@ -77,22 +84,25 @@ That's it. Form submission, `.value` access, and all native textarea behaviour w
77
84
 
78
85
  ## ✨ Features
79
86
 
80
- - 🔌 **Native Form Integration** — Works exactly like a standard `<textarea>`. No complex APIs — just use `.value` or the `name` attribute. Compatible with Django, Laravel, PHP, Rails, Node.js
87
+ - 🔌 **Native Form Integration** — Works exactly like a standard `<textarea>`. No complex APIs — just use `.value` or the `name` attribute. Compatible with Django, Laravel, PHP, Rails, Node.js, and with React or Vue via a ref and `destroy()` on unmount
81
88
  - 🔀 **WYSIWYG Hybrid Mode** — Renders bold, italic, headings, and code live as you type while keeping the underlying Markdown. Switch to plain mode for raw syntax editing
82
89
  - ⚡ **Live Preview** — Full side-by-side Markdown preview with clickable task list checkboxes that sync back to the source instantly
90
+ - 🔧 **Bring Your Own Renderer** — Swap marked for markdown-it or any other parser so the preview matches whatever your backend renders. The sanitizer is replaceable too, and DOMPurify still runs by default
91
+ - 🏷️ **Variable Dropdown** — Give template authors a menu of readable names that insert placeholders like `{{customer.name}}`. Entries can be grouped, and a sample value can stand in for the placeholder in the preview
83
92
  - 🖼️ **Advanced Image Upload** — Upload images directly to your server or S3. Avoids heavy Base64 strings for better performance and SEO
84
93
  - 🔍 **Find & Replace** — Built-in panel (`Ctrl+F` / `Ctrl+H`) with live match counter, next/prev navigation, case-sensitive toggle, and replace all
85
94
  - ⌨️ **Keyboard Shortcuts** — `Ctrl+B`, `Ctrl+I`, `Ctrl+K`, `Ctrl+Z`, `Ctrl+1`–`Ctrl+3` for headings, and more
86
95
  - 📝 **Smart List Continuation** — GitHub-style: press `Enter` inside a list and the bullet/number continues automatically
87
96
  - 🔄 **Undo / Redo** — Full diff-based history with exact cursor restoration. Works with `Ctrl+Z`, `Ctrl+Y`, `Ctrl+Shift+Z`
88
97
  - ♿ **Accessible by Default** — `role="toolbar"`, `aria-pressed`, `aria-disabled`, `disabled`, screen-reader-friendly SVGs, and correct focus restoration on modal close
89
- - 🛡️ **XSS Safe** — Preview output sanitized via [DOMPurify](https://github.com/cure53/DOMPurify) before rendering
98
+ - 🛡️ **XSS Safe** — Preview output sanitized via [DOMPurify](https://github.com/cure53/DOMPurify) before rendering, including the output of a custom renderer
90
99
  - 🛡️ **CSP Compatible** — No inline event handlers. Works with strict Content Security Policy headers
91
100
  - 🌍 **RTL Support** — Native Right-to-Left support for Arabic, Urdu, Farsi, and other RTL languages
92
101
  - 🌙 **Dark Mode & Theming** — Inherits `data-theme` from any ancestor element. Built-in light, dark, snowberry, and darkberry themes. Fully customizable via CSS variables
93
102
  - 🎛️ **Modular Toolbar** — Pick exactly which tools appear and in what order
103
+ - 🟦 **TypeScript Ready** — Definitions ship with the package. Options, toolbar entries and variable shapes are all checked, so a mistyped tool name is a compile error rather than a silently missing button
94
104
  - 📦 **Universal Module Support** — ESM, CommonJS, UMD, and IIFE. Works with Vite, webpack, Rollup, or directly via `<script src>` CDN — no configuration needed
95
- - 🚀 **High Performance** — ~116KB bundle. Debounced preview, cached layout calculations, conflict-free Tab/Enter handling for large documents
105
+ - 🚀 **High Performance** — ~52KB gzipped (245KB minified). Debounced preview, cached layout calculations, conflict-free Tab/Enter handling for large documents
96
106
 
97
107
  ## 🛠 Developer Workflow
98
108
 
@@ -137,6 +147,21 @@ const editor = new MarkdownEditor('#markdown-editor', {
137
147
  editor.destroy();
138
148
  ```
139
149
 
150
+ In React, create the editor in an effect and return `destroy` as the cleanup — that also covers StrictMode running effects twice in development:
151
+
152
+ ```jsx
153
+ useEffect(() => {
154
+ const editor = new MarkdownEditor(ref.current, { onChange });
155
+ return () => editor.destroy();
156
+ }, []);
157
+ ```
158
+
159
+ Use `defaultValue`, not `value`. The editor writes to the textarea directly, so a controlled binding (or Vue's `:value`) would overwrite what the user is typing. Full React and Vue examples are in the [documentation](https://frutjam.com/plugins/markdown-editor).
160
+
161
+ The same two rules cover Svelte, Angular and anything else: don't bind the value, and call `destroy()` on unmount. In Angular, `onChange` fires outside the zone, so wrap it in `zone.run()` for change detection to notice.
162
+
163
+ Options are read once when the editor is constructed. Changing them later has no effect — destroy the editor and create a new one instead.
164
+
140
165
  ## 📖 Documentation
141
166
 
142
167
  Full API reference, configuration options, theming guide, and advanced image upload docs:
@@ -158,6 +183,8 @@ Full API reference, configuration options, theming guide, and advanced image upl
158
183
 
159
184
  Contributions are welcome! Bug fixes, feature requests, and improvements — open an issue or submit a pull request.
160
185
 
186
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, tests, project layout, and how to add a toolbar tool.
187
+
161
188
  ---
162
189
 
163
190
  ## License